/*
 * Copyright (c) 2018-2024 北京华恒盛世科技有限公司
 * QUICKPOOL is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/

#include "subcmd.h"

static void modifyjobgroup_usage(const char *);

/**
 * @brief       qp job gmod handler, to modify a job group in the cluster.
 *
 * @param[in]   argc          #1: number of input argument
 * @param[in]   argv          #2: string array of the input argument
 *
 * @retval      0             #1: succeed
 * @retval      1             #2: input option is wrong or kind of input argument not specified
 * @retval      2             #3: argument has syntax error
 * @retval      3             #4: failed to add the job group
 */
int
cmd_modify_jobgroup(int argc, char **argv)
{
    char *strMaxJobs = NULL;
    while (TRUE) {
        int option_index = 0;
        static struct option long_options[] = {
            {"limit", required_argument, 0, 'L'},
            {"help", no_argument, 0, 'h'},
            {NULL, 0, 0, 0}
        };

        int opt;
        opt = getopt_long(argc, argv, "L:h", long_options, &option_index);
        if (-1 == opt) {
            break;
        }

        switch (opt) {
        case 'L':
            strMaxJobs = optarg;
            break;
        case 'h':
            modifyjobgroup_usage(argv[0]);
            exit(0);
        case '?':
        default:
            modifyjobgroup_usage(argv[0]);
            exit(1);
        }
    }

    if (argc <= optind) {
        fprintf(stderr, "Must specify a job group name to be modified.\n");
        modifyjobgroup_usage(argv[0]);
        exit(1);
    }

    if (NULL != strMaxJobs && 'n' != strMaxJobs[0]
        && (!isinteger(strMaxJobs) || 0 > atoi(strMaxJobs))) {

        fprintf(stderr, "%s is not a valid integer in the interval [0-%d]\n",
                strMaxJobs, INT32_MAX);
        exit(2);
    }

    char *strGroupName = argv[argc - 1]; // job group name to be modified.
    int maxJobs = INT32_MAX;
    if (NULL != strMaxJobs && 'n' != strMaxJobs[0]) {
        maxJobs = atoi(strMaxJobs);
    }

    struct request jobgroupReq;
    memset(&jobgroupReq, 0, sizeof(struct request));

    if (0 < maxJobs) { // to modify job group limit
        jobgroupReq.number = 2;

        jobgroupReq.keyvalues = (struct keyvalue *)calloc(2, sizeof(struct keyvalue));
        if (NULL == jobgroupReq.keyvalues) {
            fprintf(stderr, "calloc(%ld) failed due to %m.\n",
                    jobgroupReq.number*sizeof(struct keyvalue));
            exit(4);
        }

        jobgroupReq.keyvalues[0].key = REQUEST_KEY_NAMES;
        jobgroupReq.keyvalues[0].value = copy_string(strGroupName);

        jobgroupReq.keyvalues[1].key = REQUEST_KEY_JOBGROUP_LIMIT;
        jobgroupReq.keyvalues[1].value = (char *)calloc(12, sizeof(char));
        if (NULL == jobgroupReq.keyvalues[0].value) {
            fprintf(stderr, "calloc(%d) failed due to %m.\n", 12);
            exit(4);
        }
        snprintf(jobgroupReq.keyvalues[1].value, 12, "%d", maxJobs);
    } else {
        jobgroupReq.number = 1;

        jobgroupReq.keyvalues = (struct keyvalue *)calloc(1, sizeof(struct keyvalue));
        if (NULL == jobgroupReq.keyvalues) {
            fprintf(stderr, "calloc(%ld) failed due to %m.\n",
                    jobgroupReq.number*sizeof(struct keyvalue));
            exit(4);
        }

        jobgroupReq.keyvalues[0].key = REQUEST_KEY_NAMES;
        jobgroupReq.keyvalues[0].value = copy_string(strGroupName);
    }

    int ret;
    ret = client_modify_jobgroup(&jobgroupReq, NULL);
    if (0 != ret) {
        gf_xdr_free(gf_xdr_request, &jobgroupReq);
        exit(3);
    }

    printf("Group %s modified successfully.\n", strGroupName);
    gf_xdr_free(gf_xdr_request, &jobgroupReq);

    exit(0);
} // end function cmd_modify_jobgroup

static void
modifyjobgroup_usage(const char *cmd)
{
    fprintf(stdout, "qp job %s usage: [-h, --help]", cmd);
    fprintf(stdout, " [-L, --limit job limit] [-Ln, --limit n] group_name\n");

    return;
}

